home *** CD-ROM | disk | FTP | other *** search
-
- /*
- * $Header: udps.c,v 3.0 91/05/17 16:14:10 jrd Rel $
- * Author: J. Davin
- * Copyright 1988, 1989, Massachusetts Institute of Technology
- * See permission and disclaimer notice in file "notice.h"
- */
-
- #include <notice.h>
-
- #include <sys/types.h>
- #include <nlist.h>
- #include <sys/mbuf.h>
- #include <sys/socket.h>
- #include <netinet/in.h>
- #include <net/route.h>
- #include <netinet/in_pcb.h>
- #include <netinet/ip_var.h>
- #include <netinet/udp.h>
- #include <netinet/udp_var.h>
-
- #include <ctypes.h>
- #include <error.h>
- #include <debug.h>
- #include <local.h>
- #include <mix.h>
- #include <mis.h>
- #include <miv.h>
- #include <avl.h>
- #include <asn.h>
-
- #include <kmem.h>
- #include <udps.h>
-
- #define udpsMaxNameSize (16)
-
- typedef struct UdpsRecTag {
-
- CUnslType udpsRecAddr;
- CByteType udpsRecName [ udpsMaxNameSize ];
- CIntfType udpsRecNameLen;
- CUnslType udpsRecLAddr;
- CUnslType udpsRecFAddr;
- CUnssType udpsRecFPort;
- CUnssType udpsRecLPort;
-
- } UdpsRecType;
-
- typedef UdpsRecType *UdpsRecPtrType;
-
- static AvlIdType udpsTree;
-
- static CUnslType udpsHead;
- static CUnslType udpsZero;
-
- static CIntfType udpsDstToName (oid, n, dst)
-
- CBytePtrType oid;
- CIntfType n;
- AvlInfoType dst;
-
- {
- CBytePtrType bp;
- CIntfType k;
- CIntfType i;
- CIntfType c;
- CUnssType d;
-
- bp = (CBytePtrType) & ((UdpsRecPtrType) dst)->udpsRecLAddr;
- k = (CIntfType) 0;
- for (i = sizeof (CUnslType); (k < n) && (i != 0); i--) {
- if ((*bp & (CByteType) 0x80) != (CByteType) 0) {
- *oid++ = (CByteType) 129;
- k++;
- }
- *oid++ = (*bp++ & (CByteType) 0x7F);
- k++;
- }
- d = ((UdpsRecPtrType) dst)->udpsRecLPort;
- if ((c = ((d >> 14) & 0x03)) != (CIntfType) 0) {
- *oid++ = c | 0x80;
- k++;
- }
- if ((c = (d >> 7)) != (CUnssType) 0) {
- *oid++ = (c & 0x7F) | 0x80;
- k++;
- }
- *oid++ = (d & 0x7F);
- k++;
-
- return ((k < n) ? k : (CIntfType) -1);
- }
-
- static AvlBalanceType udpsCmpFn (info, name, namelen)
-
- AvlInfoType info;
- AvlNamePtrType name;
- AvlLengthType namelen;
-
- {
- CUnsfType n;
- CBytePtrType cp;
- CIntfType r;
-
- n = (CUnsfType) ((UdpsRecPtrType) info)->udpsRecNameLen;
- cp = ((UdpsRecPtrType) info)->udpsRecName;
- r = (CIntfType) 0;
- if (namelen >= n) {
- while ((n-- != 0) && ((r = (CIntfType) *name++ -
- (CIntfType) *cp++) == 0));
- }
- else {
- while ((namelen-- != 0) && ((r = (CIntfType) *name++ -
- (CIntfType) *cp++) == 0));
- if (r == 0) {
- r = -1;
- }
- }
-
- if (r == 0) {
- return (avlDirBalanced);
- }
- else if (r < 0) {
- return (avlDirLeft);
- }
- else {
- return (avlDirRight);
- }
- }
-
- static AsnIdType udpsRetrieve (mix, info)
-
- MixCookieType mix;
- AvlInfoType info;
-
- {
- AsnIdType result;
-
- switch ((int) mix) {
-
- case 0:
- result = asnOctetString (asnClassApplication,
- (AsnTagType) 0,
- (CBytePtrType) & ((UdpsRecPtrType) info)->udpsRecLAddr,
- (AsnLengthType) 4);
- break;
-
- case 1:
- result = asnUnsl (asnClassUniversal, (AsnTagType) 2,
- (CUnslType) ((UdpsRecPtrType) info)->udpsRecLPort);
- break;
-
- default:
- result = (AsnIdType) 0;
- break;
- }
- return (result);
- }
-
- static CUnslType udpsRefreshEntry (last, location)
-
- CUnslType last;
- CUnslType location;
-
- {
- struct inpcb inpcbBuf;
- struct inpcb *rp;
- AvlInfoType info;
- UdpsRecPtrType ri;
- UdpsRecType rb;
-
- if (kmemRead ((CBytePtrType) & inpcbBuf, (CIntfType) sizeof (inpcbBuf),
- location) != (CIntfType) sizeof (inpcbBuf)) {
- return ((CUnslType) 0);
- }
-
- /*
- * Did things change under us since our last dip
- * into the kernel?
- */
-
- if (inpcbBuf.inp_prev != (struct inpcb *) last) {
- return ((CUnslType) 0);
- }
-
- rp = & inpcbBuf;
- DEBUG0 ("udpsRefreshEntry:\n");
- DEBUG1 ("INPCB at %X\n", location);
- DEBUG1 ("INPCB.inp_prev: %X\n", rp->inp_prev);
- DEBUG1 ("INPCB.inp_next: %X\n", rp->inp_next);
- DEBUG1 ("INPCB.inp_laddr: %X\n", rp->inp_laddr);
- DEBUG1 ("INPCB.inp_faddr: %X\n", rp->inp_faddr);
- DEBUG1 ("INPCB.inp_lport: %d\n", rp->inp_lport);
- DEBUG1 ("INPCB.inp_fport: %d\n", rp->inp_fport);
- DEBUG1 ("INPCB.inp_ppcb: %X\n", rp->inp_ppcb);
- DEBUG1 ("INPCB.inp_socket: %X\n", rp->inp_socket);
-
- rb.udpsRecLAddr = (CUnslType) rp->inp_laddr.s_addr;
- rb.udpsRecLPort = (CUnssType) ntohs (rp->inp_lport);
- rb.udpsRecFAddr = (CUnslType) rp->inp_faddr.s_addr;
- rb.udpsRecFPort = (CUnssType) ntohs (rp->inp_fport);
- rb.udpsRecNameLen = udpsDstToName (rb.udpsRecName,
- (CIntfType) sizeof (rb.udpsRecName),
- (AvlInfoType) & rb);
- rb.udpsRecAddr = location;
-
- info = avlFind (udpsTree, (AvlNamePtrType) rb.udpsRecName,
- (AvlLengthType) rb.udpsRecNameLen);
- if (info != (AvlInfoType) 0) {
- ((UdpsRecPtrType) info)->udpsRecAddr = location;
- return ((CUnslType) inpcbBuf.inp_next);
- }
-
- ri = (UdpsRecPtrType) malloc ((unsigned) sizeof (*ri));
- if (ri != (UdpsRecPtrType) 0) {
- *ri = rb;
- (void) avlInsert (udpsTree, (AvlNamePtrType) rb.udpsRecName,
- (AvlLengthType) rb.udpsRecNameLen, (AvlInfoType) ri);
- }
-
- return ((CUnslType) rp->inp_next);
- }
-
- static CVoidType udpsRefreshChain (location)
-
- CUnslType location;
-
- {
- CUnsfType i;
- CUnslType head;
- CUnslType prev;
- CUnslType next;
-
- if (kmemRead ((CBytePtrType) & head,
- (CIntfType) sizeof (head), location) ==
- (CIntfType) sizeof (head)) {
- prev = location;
- while ((head != (CUnslType) 0) &&
- (head != location)) {
- next = udpsRefreshEntry (prev, head);
- prev = head;
- head = next;
- }
- }
- }
-
- static AvlIdType udpsFreeChain (tree)
-
- AvlIdType tree;
-
- {
- AvlInfoType info;
- CByteType name [ udpsMaxNameSize ];
- AvlLengthType namelen;
-
- namelen = (AvlLengthType) 0;
- while ((info = avlCessor (tree, (AvlNamePtrType) name,
- namelen)) != (AvlInfoType) 0) {
- namelen = ((UdpsRecPtrType) info)->udpsRecNameLen;
- bcopy ((char *) ((UdpsRecPtrType) info)->udpsRecName,
- (char *) name, (int) namelen);
- (void) free ((char *) info);
- }
- return (avlFree (tree));
- }
-
- static CVoidType udpsRefresh ()
-
- {
- udpsTree = udpsFreeChain (udpsTree);
- udpsTree = avlNew (udpsCmpFn, (AvlPrintFnType) 0);
- udpsRefreshChain (udpsHead);
- }
-
- static MixStatusType udpsRelease (cookie)
-
- MixCookieType cookie;
-
- {
- cookie = cookie;
- return (smpErrorGeneric);
- }
-
- static MixStatusType udpsCreate (cookie, name, namelen, asn)
-
- MixCookieType cookie;
- MixNamePtrType name;
- MixLengthType namelen;
- AsnIdType asn;
-
- {
- cookie = cookie;
- name = name;
- namelen = namelen;
- asn = asn;
- return (smpErrorGeneric);
- }
-
- static MixStatusType udpsDestroy (cookie, name, namelen)
-
- MixCookieType cookie;
- MixNamePtrType name;
- MixLengthType namelen;
-
- {
- cookie = cookie;
- name = name;
- namelen = namelen;
- return (smpErrorGeneric);
- }
-
- static AsnIdType udpsGet (cookie, name, namelen)
-
- MixCookieType cookie;
- MixNamePtrType name;
- MixLengthType namelen;
-
- {
- AvlInfoType info;
-
- udpsRefresh ();
- info = avlFind (udpsTree, (AvlNamePtrType) name,
- (AvlLengthType) namelen);
- if (info == (AvlInfoType) 0) {
- return ((AsnIdType) 0);
- }
- else {
- return (udpsRetrieve (cookie, info));
- }
- }
-
- static MixStatusType udpsSet (cookie, name, namelen, asn)
-
- MixCookieType cookie;
- MixNamePtrType name;
- MixLengthType namelen;
- AsnIdType asn;
-
- {
- cookie = cookie;
- name = name;
- namelen = namelen;
- asn = asn;
- return (smpErrorGeneric);
- }
-
- static AsnIdType udpsNext (cookie, name, namelenp)
-
- MixCookieType cookie;
- MixNamePtrType name;
- MixLengthPtrType namelenp;
-
- {
- AvlInfoType info;
- AsnIdType result;
-
- udpsRefresh ();
- do {
-
- info = avlCessor (udpsTree, (AvlNamePtrType) name,
- (AvlLengthType) *namelenp);
- if (info != (AvlInfoType) 0) {
- (void) bcopy ((char *)
- ((UdpsRecPtrType) info)->udpsRecName, (char *) name,
- (int) ((UdpsRecPtrType) info)->udpsRecNameLen);
- *namelenp = (MixLengthType)
- ((UdpsRecPtrType) info)->udpsRecNameLen;
- result = udpsRetrieve (cookie, info);
- }
- else {
- result = (AsnIdType) 0;
- }
-
- } while ((info != (AvlInfoType) 0) && (result == (AsnIdType) 0));
-
- return (result);
- }
-
- static AsnIdType udpsStatGet (cookie, name, namelen)
-
- MixCookieType cookie;
- MixNamePtrType name;
- MixLengthType namelen;
-
- {
- AsnIdType result;
- struct udpstat stats;
-
- if (namelen != (MixLengthType) 1) {
- result = (AsnIdType) 0;
- }
- else if (*name != (MixNameType) 0) {
- result = (AsnIdType) 0;
- }
- else if (kmemRead ((CBytePtrType) & stats,
- (CIntfType) sizeof (stats), (CUnslType) cookie) !=
- (CIntfType) sizeof (stats)) {
- result = (AsnIdType) 0;
- }
- else {
- result = asnUnsl (asnClassApplication,
- (AsnTagType) 1,
- (CUnslType) stats.udps_hdrops +
- stats.udps_badlen + stats.udps_badsum);
- }
- return (result);
- }
-
- static AsnIdType udpsStatNext (cookie, name, namelenp)
-
- MixCookieType cookie;
- MixNamePtrType name;
- MixLengthPtrType namelenp;
-
- {
- AsnIdType result;
- struct udpstat stats;
-
- if (*namelenp != (MixLengthType) 0) {
- result = (AsnIdType) 0;
- }
- else if (kmemRead ((CBytePtrType) & stats,
- (CIntfType) sizeof (stats), (CUnslType) cookie) !=
- (CIntfType) sizeof (stats)) {
- result = (AsnIdType) 0;
- }
- else {
- result = asnUnsl (asnClassApplication,
- (AsnTagType) 1,
- (CUnslType) stats.udps_hdrops +
- stats.udps_badlen + stats.udps_badsum);
- *namelenp = (MixLengthType) 1;
- *name = (MixNameType) 0;
- }
- return (result);
- }
-
- static MixOpsType udpsOps = {
-
- udpsRelease,
- udpsCreate,
- udpsDestroy,
- udpsNext,
- udpsGet,
- udpsSet
-
- };
-
- static MixOpsType udpsStatOps = {
-
- udpsRelease,
- udpsCreate,
- udpsDestroy,
- udpsStatNext,
- udpsStatGet,
- udpsSet
-
- };
-
- CVoidType udpsInit ()
-
- {
- struct nlist nl [ 4 ];
-
- nl [ 0 ].n_name = "_udb";
- nl [ 1 ].n_name = "_udpstat";
- nl [ 2 ].n_name = (char *) 0;
- if (nlist ("/vmunix", nl) != 0) {
- return;
- }
- udpsHead = (CUnslType) nl [ 0 ].n_value;
-
- (void) misExport ((MixNamePtrType) "\53\6\1\2\1\7\5\1\1",
- (MixLengthType) 9, & udpsOps, (MixCookieType) 0);
- (void) misExport ((MixNamePtrType) "\53\6\1\2\1\7\5\1\2",
- (MixLengthType) 9, & udpsOps, (MixCookieType) 1);
- /*
- * When the kernel doesn't count it, export a zero
- */
- udpsZero = (CUnslType) 0;
- (void) mivCounterRO ((MixNamePtrType) "\53\6\1\2\1\7\1",
- (MixLengthType) 7, & udpsZero);
- (void) mivCounterRO ((MixNamePtrType) "\53\6\1\2\1\7\2",
- (MixLengthType) 7, & udpsZero);
- (void) misExport ((MixNamePtrType) "\53\6\1\2\1\7\3",
- (MixLengthType) 7, & udpsStatOps,
- (MixCookieType) nl [ 1 ].n_value);
- (void) mivCounterRO ((MixNamePtrType) "\53\6\1\2\1\7\4",
- (MixLengthType) 7, & udpsZero);
-
- udpsTree = avlNew (udpsCmpFn, (AvlPrintFnType) 0);
- }
-
-